/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.task.zkex.simple;

import cn.easyplatform.EasyPlatformWithLabelKeyException;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.messages.request.GetListRequestMessage;
import cn.easyplatform.messages.response.GetListResponseMessage;
import cn.easyplatform.messages.vos.GetListVo;
import cn.easyplatform.spi.service.ComponentService;
import cn.easyplatform.type.FieldVo;
import cn.easyplatform.type.IResponseMessage;
import cn.easyplatform.web.ext.ComponentBuilder;
import cn.easyplatform.web.ext.Widget;
import cn.easyplatform.web.ext.ZkExt;
import cn.easyplatform.web.ext.calendar.Calendars;
import cn.easyplatform.web.ext.calendar.api.CalendarEvent;
import cn.easyplatform.web.ext.calendar.event.CalendarsEvent;
import cn.easyplatform.web.ext.calendar.event.KalendarEvent;
import cn.easyplatform.web.ext.calendar.impl.SimpleCalendarEvent;
import cn.easyplatform.web.ext.calendar.impl.SimpleCalendarModel;
import cn.easyplatform.web.ext.zul.Kalendars;
import cn.easyplatform.web.service.ServiceLocator;
import cn.easyplatform.web.task.OperableHandler;
import cn.easyplatform.web.task.event.EventListenerHandler;
import cn.easyplatform.web.task.support.scripting.UtilsCmd;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.zkoss.util.Locales;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Row;
import org.zkoss.zul.Rows;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class KalendarsBuilder extends AbstractQueryBuilder<Kalendars> implements Widget, EventListener<Event> {

    public KalendarsBuilder(OperableHandler mainTaskHandler, Kalendars comp) {
        super(mainTaskHandler, comp);
    }

    @Override
    public Component build() {
        if (me.getCols() <= 0)
            throw new EasyPlatformWithLabelKeyException(
                    "component.property.not.found", "<kalendar>", "cols");
        me.setAttribute("$proxy", this);
        me.appendChild(new Rows());
        load();
        return me;
    }

    @Override
    public void reload(Component widget) {
        me.getRows().getChildren().clear();
        load();
    }

    protected void createModel(List<?> data) {
        me.setZclass("z-kalendars");
        Row row = null;
        Calendar calendar = Calendar.getInstance();
        if (me.getCurrentYear() == 0)
            me.setCurrentYear(calendar.get(Calendar.YEAR));
        List<Calendars> calendarss = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            if (i % me.getCols() == 0) {
                row = new Row();
                row.setZclass("z-kalendars-cnt");
                me.getRows().appendChild(row);
            }
            calendar.set(me.getCurrentYear(), i, 1);
            Calendars calendars = new Calendars();
            calendars.setFirstDayOfWeek(me.getFirstDayOfWeek());
            calendars.setDisabled(me.isDisabled());
            calendars.setMold("year");
            calendars.setCurrentDate(calendar.getTime());
            calendars.setModel(new SimpleCalendarModel(new ArrayList<CalendarEvent>(), true));
            if (!Strings.isBlank(me.getEvent())) {
                calendars.addEventListener(CalendarsEvent.ON_EVENT_CREATE, this);
                calendars.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
            }
            if (!Strings.isBlank(me.getTooltipEvent()))
                calendars.addEventListener(CalendarsEvent.ON_EVENT_TOOLTIP, this);
            row.appendChild(calendars);
            calendarss.add(calendars);
        }
        if (data != null) {
            for (Object obj : data) {
                Date date = null;
                if (obj instanceof Date) {
                    date = (Date) obj;
                } else if (obj instanceof FieldVo[]) {
                    date = (Date) ((FieldVo[]) obj)[0].getValue();
                } else if (obj instanceof FieldVo) {
                    date = (Date) ((FieldVo) obj).getValue();
                }
                if (date != null) {
                    calendar.setTime(date);
                    if (calendar.get(Calendar.YEAR) == me.getCurrentYear()) {
                        Calendars calendars = calendarss.get(calendar.get(Calendar.MONTH));
                        SimpleCalendarEvent ce = new SimpleCalendarEvent();
                        ce.setId(DateFormatUtils.format(date, "yyyyMMdd"));
                        ce.setBeginDate(date);
                        calendar.add(Calendar.DAY_OF_YEAR, 1);
                        ce.setEndDate(calendar.getTime());
                        ce.setLocked(me.isDisabled());
                        if (obj instanceof FieldVo[]) {
                            FieldVo[] fds = (FieldVo[]) obj;
                            if (fds.length > 1) {
                                ce.setTitle((String) fds[1].getValue());
                                ce.setContent(ce.getTitle());
                            }
                            if (fds.length > 2) {
                                ce.setHeaderColor((String) fds[2].getValue());
                                ce.setContentColor(ce.getHeaderColor());
                            }
                        }
                        ((SimpleCalendarModel) calendars.getModel()).add(ce);
                    }
                }
            }
        }
        calendarss.clear();
        calendarss = null;
    }

    private CalendarEvent getCalendarEvent(CalendarsEvent evt) {
        Date[] calendarDates = getCalendarDates(evt);
        Iterator<Component> itr = me.queryAll("calendars").iterator();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        while (itr.hasNext()) {
            Calendars calendars = (Calendars) itr.next();
            for (Date cd : calendarDates) {
                CalendarEvent ce = calendars.getModel().getEventById(sdf.format(cd));
                if (ce != null)
                    return ce;
            }
        }
        return null;
    }

    private Date[] getCalendarDates(CalendarsEvent evt) {
        Calendar firstCalendar = Calendar.getInstance(Locales.getCurrent());
        firstCalendar.setTime(evt.getBeginDate());
        Calendar secondCalendar = Calendar.getInstance(Locales.getCurrent());
        secondCalendar.setTime(evt.getEndDate());
        if (firstCalendar.after(secondCalendar)) {
            Calendar calendar = firstCalendar;
            firstCalendar = secondCalendar;
            secondCalendar = calendar;
        }
        long calendarNum1 = firstCalendar.getTimeInMillis();
        long calendarNum2 = secondCalendar.getTimeInMillis();
        int days = Math.abs((int) ((calendarNum1 - calendarNum2) / UtilsCmd.C_ONE_DAY));
        List<Date> dates = new ArrayList<>();
        dates.add(evt.getBeginDate());
        if (days > 1) {
            for (int i = 1; i < days; i++) {
                firstCalendar.add(Calendar.DAY_OF_YEAR, 1);
                dates.add(firstCalendar.getTime());
            }
        }
        Date[] calendarDates = new Date[dates.size()];
        dates.toArray(calendarDates);
        return calendarDates;
    }

    @Override
    public void onEvent(Event event) throws Exception {
        CalendarsEvent evt = (CalendarsEvent) event;
        KalendarEvent kevt = new KalendarEvent(event.getName(), event.getTarget());
        if (event.getName().equals(CalendarsEvent.ON_EVENT_TOOLTIP)) {
            me.setEvents(evt);
            EventListenerHandler elh = new EventListenerHandler(event.getName(), main, me.getTooltipEvent(), anchor);
            elh.onEvent(evt);
        } else if (event.getName().equals(CalendarsEvent.ON_EVENT_EDIT)) {
            kevt.setTitle(evt.getTitle());
            kevt.setColor(evt.getContentColor());
            kevt.setDate(new Date[]{evt.getBeginDate()});
            kevt.setEdit(true);
            me.setEvents(kevt);
            EventListenerHandler elh = new EventListenerHandler(event.getName(), main, me.getEvent(), anchor);
            elh.onEvent(kevt);
        } else {
            CalendarEvent ce = getCalendarEvent((CalendarsEvent) event);
            Date[] calendarDates = getCalendarDates(evt);
            if (ce != null) {
                if (calendarDates.length == 1) {//取事件变成ON_EVENT_EDIT事件
                    kevt.setEdit(true);
                    kevt.setColor(ce.getContentColor());
                    kevt.setTitle(ce.getTitle());
                    kevt.setDate(new Date[]{ce.getBeginDate()});
                } else//多日期不做处理
                    return;
            } else {
                kevt.setTitle(evt.getTitle());
                kevt.setColor(evt.getContentColor());
                kevt.setDate(getCalendarDates(evt));
            }
            me.setEvents(kevt);
            EventListenerHandler elh = new EventListenerHandler(event.getName(), main, me.getEvent(), anchor);
            elh.onEvent(kevt);
        }
    }
}
